/**
 * Copyright (C), 2015-2021, 开度
 * FileName: UserInfoServie
 * Author:   ASUS
 * Date:     2021/4/19 17:56
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * Hezeyu           2021/4/19           1.0
 */
package com.example.spring.security.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.spring.security.dto.UserInfoDto;
import com.example.spring.security.exception.ErrCode;
import com.example.spring.security.interceptor.user.CustomUserDetailsService;
import com.example.spring.security.mapper.UserInfoMapper;
import com.example.spring.security.pojo.UserPojo;
import com.example.spring.security.utils.BaseResponse;
import com.example.spring.security.utils.PageUtils;
import com.example.spring.security.utils.PasswordEncoderUtils;
import com.example.spring.security.utils.RequestIdUtil;
import com.example.spring.security.vo.UserInfoManagerVo;
import com.example.spring.security.vo.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 〈〉
 *
 * @author ASUS
 * @create 2021/4/19
 * @since 1.0.0
 */
@Service
@Slf4j
public class UserInfoServie {

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    RequestIdUtil requestIdUtil;

    @Autowired
    private AuthenticationManager authenticationManager;


    public UserPojo getUserInfo(String username){
        return userInfoMapper.findOneByLogin(username);
    }

    public BaseResponse inset(UserPojo userPojo) throws Exception {
        BaseResponse baseResponse=new BaseResponse();
        if(exist(userPojo.getUsername())){
            baseResponse.setFail("用户名已存在",null,"002","1211212");
        }else {
            userPojo.setPassword(PasswordEncoderUtils.encode(userPojo.getPassword()));
            baseResponse.setSuccess("创建成功",userInfoMapper.insert(userPojo),"111");
        }
        return baseResponse;
    }

    /**
     *
     * 查询用户信息
     * @param userInfoManagerVo
     * @return:com.example.spring.security.utils.BaseResponse<com.example.spring.security.utils.PageUtils<com.example.spring.security.pojo.UserPojo>>
     * @since: 1.0.0
     * @Author:hezeyu
     * @Date: 2021/4/28 18:24
     */
    public BaseResponse<PageUtils<UserPojo>> select(UserInfoManagerVo userInfoManagerVo){
        BaseResponse<PageUtils<UserPojo>> baseResponse=new BaseResponse<>();
        QueryWrapper<UserPojo> queryWrapper=new QueryWrapper<>();

        String userName = userInfoManagerVo.getUserName();
        String role = userInfoManagerVo.getRole();
        if(!"".equals(userName) && userName!=null){
            queryWrapper.eq("username",userName);
        }
        if(!"".equals(role) && role!=null){
            queryWrapper.eq("role",role);
        }

        IPage<UserPojo>page=new Page<>();
        page.setSize(userInfoManagerVo.getSize());
        page.setCurrent(userInfoManagerVo.getCurrent());
        PageUtils<UserPojo> pojoPageUtils= new PageUtils<>();
        pojoPageUtils.toPageUtis(userInfoMapper.selectPage(page, queryWrapper));
        baseResponse.setSuccess("查询成功",pojoPageUtils,requestIdUtil.get());
        return baseResponse;
    }

    /**
     *
     *  用户登录
     * @param userInfoVo
     * @return:com.example.spring.security.utils.BaseResponse<com.example.spring.security.dto.UserInfoDto>
     * @since: 1.0.0
     * @Author:hezeyu
     * @Date: 2021/4/29 14:19
     */
    public BaseResponse<UserInfoDto> login(UserInfoVo userInfoVo){
        BaseResponse<UserInfoDto> baseResponse=new BaseResponse<>();
        try {
//            log.info("进入登录方法");
//            // 1 创建UsernamePasswordAuthenticationToken
//            UsernamePasswordAuthenticationToken token
//                    = new UsernamePasswordAuthenticationToken(userInfoVo.getUsername(), userInfoVo.getPassword());
//            // 2 认证
//            Authentication authentication = authenticationManager.authenticate(token);
//            // 3 保存认证信息
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//            // 4 加载UserDetails
//            UserDetails details = userDetailsService.loadUserByUsername(userInfoVo.getUsername());
//            UserInfoDto userInfoDto=new UserInfoDto();
//            userInfoDto.setUserName(details.getUsername());
//
//            userInfoDto.setToken(TokenProvider.token(userInfoVo.getUsername(),userInfoVo.getPassword()));
            // 1 创建UsernamePasswordAuthenticationToken
            UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(userInfoVo.getUsername(), userInfoVo.getPassword());
            // 2 认证
            Authentication authenticate = authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(authenticate);
            UserInfoDto userInfo = (UserInfoDto) authenticate.getPrincipal();

            baseResponse.setSuccess("查询成功",userInfo,requestIdUtil.get());
        }catch (Exception e){
            log.error(e.getMessage());
            baseResponse.setFail("登录失败",null, ErrCode.loginException.getErrCode(),requestIdUtil.get());
        }finally {
            return baseResponse;
        }
    }
    /**
     * 判断用户是否存在
     */
    private boolean exist(String username) {
        UserPojo userDO = userInfoMapper.findOneByLogin(username);
        return (userDO != null);
    }

}
